package bdqn.hfxt;

import java.util.Arrays;
import java.util.Scanner;

public class Demo {
    public static void main(String[] args) {
        /**
         * 数组：一个存储类型相同长度固定的多个值的变量。
         *      在内存中开辟一段连续的空间。
         * 数组的组成：
         *     标识符[数组名]      --> 一个内存地址
         *     数组元素[数组里的值] --> 将一个地址划分多个区域，每个区域存储一个值
         *     元素类型[值的类型]   --> 开辟多大空间[值的类型和数组类型一致]
         *     元素下标[元素顺序]   --> 地址中的不同区域
         *
         *  数组的定义：
         *     1）声明数组              1）声明变量
         *       数据类型[] 数组名;         数据类型  变量名;
         *     2）分配空间
         *       数组名 = new 数据类型[长度];
         *     3）赋值                 2） 赋值
         *       数组名[下标] = 值;         变量名 = 值;
         *  简化语法：
         *      1、声明并分配空间
         *        数据类型[] 数组名 = new 数据类型[长度];
         *      2、声明、分配空间和赋值
         *        数据类型[] 数组名 = new 数据类型[]{值,值}
         *        数据类型[] 数组名 = {值,值}
         *  注意：
         *       系统会在数组分配空间后，赋初始值 int 0, double 0.0, char '', String null
         *       使用数组的数据时一定会用到下标来区分区域。
         *       数组的下标从0开始
         *       声明、分配空间和赋值综合一起的这种语法，数组的长度，要求不写长度，由{}里的值的个数决定。
         *            每个值用逗号隔开
         *            允许声明和初始值分开写
         *            但是简化写法不支持分开写，只能在同一行写。
         *       数组通过长度属性length来获取数组元素个数，写法：数组名.length；
         *       数组一旦分配空间，长度就固定。如果取数据使用的下标超过最大下标，就会报错java.lang.ArrayIndexOutOfBoundsException
         *       数组数据和下标的关系：
         *            数组长度-1 是数组最大下标值  例如：数组名[最大下标=数组名.length-1]
         *
         *  数组的使用场景：
         *  1）结合循环实现给数组元素赋值，或输出数组元素
         *  2）结合循环实现获取数组中的数据和，或平均值等
         *  3）结合循环求数组里的最大值和最小值
         *      先保证数组里的数据完整
         *      将数组第一个值赋给擂台变量
         *      再从数组第二个值开始循环比较
         *  4）对数组的数据做排序[从小到大、从大到小]
         *      通过数组处理类Arrays里的sort方法，能做升序排序。
         *  5）插入排序[往数组中插入一个数，仍保证顺序不变]
         *     定义长度多一位的新数组[先保证数组能放下多一位]
         *     将老数组的数据存储放到新数组中[值,值,默认值]
         *     有顺序之后获取插入数的位置[找数组中第一个比插入数大的下标]
         *     下标后面的数往后挪一位
         *     待插入数添加到指定的插入位置
         */
        //声明
        int[] ages;
        //分配空间
        ages = new int[3];
        //赋值
        ages[0] = 10;
        ages[1] = 20;
        ages[2] = 30;

        System.out.println(ages[0]);
        System.out.println(ages[1]);
        System.out.println(ages[2]);

        //声明并分配空间
        double[] score = new double[3];
        System.out.println(score[0]);
        System.out.println(score[1]);
        System.out.println(score[2]);

        //声明、分配空间和赋值
        char[] zf = new char[]{'a','b','c'};
        System.out.println(zf[0]);
        System.out.println(zf[1]);
        System.out.println(zf[2]);
        //简化语法
        String[] strs = {"zhangsan","lisi","wangwu"};
        System.out.println(strs[0]);
        System.out.println(strs[1]);
        System.out.println(strs[2]);

        boolean[] br;
        br = new boolean[]{true,false};
        System.out.println(br[0]);
        System.out.println(br[1]);
        //System.out.println(br[2]); //数组越界错误ArrayIndexOutOfBoundsException
//        boolean[] br2;
//        br = {true,false};
        System.out.println(br.length);
        System.out.println(strs.length);
        System.out.println(strs[strs.length-1]);

        System.out.println("--------------------------------");
        Scanner input = new Scanner(System.in);
        //使用场景一：结合循环遍历数组
        //录入三个同学的分数，并输入显示
//        double[] scores = new double[3];
//        for(int i=0; i<scores.length; i++){ //循环的值就是数组下标
//            System.out.println("请输入第" + i + "个下标的值：");
//            scores[i] = input.nextDouble();
//        }
//        for(int i=0; i<scores.length; i++) { //循环的值就是数组下标
//            System.out.println("下标第" + i + "个值：" + scores[i]);
//        }

        //使用场景二：结合循环遍历数组统计和与平均值
        //录入五个商品价格，统计商品均价
//        double[] prices = new double[5];
//        //总价
//        double sum = 0;
//        for(int i=0; i<prices.length; i++) { //循环的值就是数组下标
//            System.out.println("请输入第" + (i+1) + "件商品价格：");
//            prices[i] = input.nextDouble();
//            //求和
//            sum += prices[i];
//        }
//        //平均值
//        double avg = sum / prices.length;
//        System.out.println("均价：" + avg);

        //使用场景三：结合循环遍历数组求最值
        //录入三个英文字符，输出最大最小字符
//        char[] chs = new char[3];
//        //先将数组中的数据填充完毕
//        for(int i=0; i<chs.length; i++){
//            System.out.println("请输入第" + (i+1) + "个字符：");
//            chs[i] = input.next().charAt(0);
//        }
//        //赋擂台值
//        char max = chs[0];
//        char min = chs[0];
//        //循环比较
//        for(int j=1; j<chs.length; j++){//循环的值就是数组下标
//            //数组数比擂台数大，将数组中的值存储到擂台变量上
//            if(chs[j] > max){
//                max = chs[j];
//            }
//            if(chs[j] < min){
//                min = chs[j];
//            }
//        }
//        System.out.println("最大值是：" + max + "，最小值是：" + min);

        //使用场景四：对数组中的元素排序 [升序降序]
        //录入5个同学的年龄，并对它排序
//        int[] counts = new int[5];
//        for (int i=0; i<counts.length; i++){
//            System.out.println("请输入第"+(i+1)+"个年龄：");
//            counts[i] = input.nextInt();
//        }
//        System.out.println("原始顺序：");
//        for (int i=0; i<counts.length; i++) {
//            System.out.print(counts[i] + "\t");
//        }
        //升序排序
        //Arrays.sort(counts);

//        System.out.println("\n升序排序：");
//        for (int i=0; i<counts.length; i++) {
//            System.out.print(counts[i] + "\t");
//        }
//
//        System.out.println("\n逆序输出：");
//        for (int i=counts.length-1; i>=0; i--){
//            System.out.print(counts[i] + "\t");
//        }
        //冒泡排序法：二重循环
        //外层循环：n-1
        //内层循环：n-1-i
        //初始值从0开始，内外层条件写<
        //内层循环里，前一个数比后一个数大，调整顺序  > --> 升序
        //          前一个数比后一个数小，调整顺序  < --> 降序
//        for(int i=0;i<counts.length-1; i++){//轮数
//            for(int j=0; j<counts.length-1-i; j++){//每轮次数
//                //升序排序用>  降序排序用<
//                if(counts[j] < counts[j+1]){
//                    int temp = counts[j];
//                    counts[j] = counts[j+1];
//                    counts[j+1] = temp;
//                }
//            }
//        }
//        System.out.println("\n冒泡排序后：");
//        for (int i=0; i<counts.length; i++) {
//            System.out.print(counts[i] + "\t");
//        }

//        012345
//        2578911   8

        //使用场景五：插入排序，
        int[] oldArr = {9,5,2,7};
        //  排序
        Arrays.sort(oldArr);
        //1、定义长度+1的新数组
        int[] newArr = new int[oldArr.length+1];
        //2、老数组数据存储到新数组中[循环老数组长度]
        for(int i=0;i<oldArr.length; i++){
            newArr[i] = oldArr[i];
        }
        //3、定义变量存储待插入的数
        int num = 4;
        //4、找插入位置[找数组中第一个比插入数大的数的下标]
        int index=-1;
        for(int i=0;i<oldArr.length; i++){
            if(oldArr[i] > num){
                index = i;
                break;
            }
        }
        //5、在新数组中，从插入位置开始，将后续有效数据往后挪一位
        for (int i=newArr.length-1; i>=index; i--){
            //后挪一位
            newArr[i] = newArr[i-1];
        }
        //6、将待插入数插入到指定位置
        newArr[index] = num;

        System.out.println("--------------------------");
        for (int i=0; i<newArr.length; i++) {
            System.out.print(newArr[i] + "\t");
        }
    }
}
